home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 52
/
Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso
/
Aminet
/
misc
/
emu
/
Apex-src.lha
/
XPL68K.DOC
< prev
next >
Wrap
Text File
|
2001-09-30
|
8KB
|
248 lines
XPL68K.DOC APR-12-87
This is a collection of notes related to running XPL, V5.7 on the 68000
in 32-bit mode.
REGISTER USAGE
The top of the working stack is kept in data registers and is called a
pseudo stack. The compiler keeps track of the pseudo stack pointer and
generates the appropriate data register numbers. When this pseudo stack
overflows, the compiler will generate code which pushes these registers
onto the real stack.
The registers are used as follows:
D0 - Scratch
D1 - Pseudo stack (start)
D2 - |
D3 - |
D4 - |
D5 - Pseudo stack (end)
D6 - Register variable (if used)
D7 - Register variable (if used)
A0 - Frame pointer, level 0
A1 - |
A2 - |
A3 - |
A4 - Frame pointer, level 4
A5 - Heap pointer
A6 - Scratch
A7 - Stack pointer (SP)
All XPL variables and arrays are stored in a data structure called a
heap. A heap is similar to a stack but it grows upward in memory, and it
is less restrictive about how data is "pushed" onto it. In addition to a
heap pointer there are frame pointers which point to the base address of
variables corresponding to each level of (static) procedure nesting.
STRING TERMINATION
The convention for terminating strings has been changed. Strings are now
terminated with a zero byte instead of having the most significant bit
set on the last character. This allows using the 128 additional char-
acters defined by the (IBM) extended ASCII set. This also makes it
simpler to perform string operations such as concatenation.
SHIFT OPERATORS
Shift operators have been added to partially compensate for the slower
32-bit multiply and divide routines (shifts may be used to replace most
multiplications and divisions by powers of 2). The general form of the
shift expressions are:
EXPR << EXPR or EXPR >> EXPR
EXPR is an integer sub-expression (a 32-bit value), "<<" indicates shift
to the left, and ">>" means shift to the right. The sub-expression to the
right of the shift operator specifies the number of bits to shift. This
should be a positive value in the range 0 through 63. Shifting more than
31 bits will alway give a zero result. Here are some examples:
1 << 1 = 2
$30 << 2 = $C0
$50 >> 4 = $05
$FFFFFF5A >> 4 = $0FFFFFF5
The shift operator's precedence is between the unary operators, and the
multiplication and division operators. Thus the following pairs of
expressions are equivalent:
-1 >>16 *2 = (-1 >>16) *2 = $1FFFE
2+1 <<8 = 2 + (1 <<8) = $102
MORE OPERATORS
An "exclusive or" operator has been added. It is indicated by the
vertical bar symbol (|). "Exclusive or" has the same precedence as the
"or" operator (!).
The tilde (~) can be used to indicate the ones complement operation. It
is exactly the same as the existing 'NOT' operator; it is just a more
compact notation.
For example:
A | B = A&~B ! ~A&B = (A & 'NOT'B) ! ('NOT'A & B)
REGISTER VARIABLES
A procedure can run as much as twice as fast if its variables are in
registers instead of memory. Thus the 'REGISTER' declaration:
'REGISTER' 'INTEGER' A, B;
This declares A and B as integers which are to be kept in registers.
The registers are taken from the top of the pseudo stack. You can have
five of them in scope at one time, but be aware that this may actually
slow things down since the pseudo stack will need to be pushed and pulled
more often.
The only other restriction is that you can't, of course, get the address
of a register variable, as with:
X:= 'ADDR' A;
Register variables can receive arguments, and can be used for addresses
and reals, for example:
'REGISTER' 'ADDR' PORT;
'REGISTER' 'REAL' ANGLE, DISTANCE;
INTERCHANGEABLE CODE
XPL code and assembly code may be mixed in a much more straightforward
manner than before.
XPL code can run in either user or supervisor mode.
XPL code can be called from assembly language code. The XPL code only
requires that in addition to a stack, pointed to by A7, a heap, pointed
to by A5, must be provided. Separately compiled XPL programs can be
called as subroutines from either XPL or assembly language.
D0 and A6 are used as scratch registers by XPL code and are not saved and
restored.
Procedures, intrinsics, and externals are all handled the same way. They
all receive arguments on the heap. For example, if the heap pointer, A5,
is at location 10000, then the call FROG(A, B, C) will copy the arguments
into these locations:
A5 --> 10000: A
10004: B
10008: C
Any procedure, intrinsic, or external which is used as a function will
return its value in D0.
The result is that a program calling a subroutine need not know if the
subroutine was written in XPL or assembly language.
OTHER ITEMS
The order of the arguments in the BLIT intrinsic has changed. Before the
order was: BLIT(TO, FROM, SIZE), now it is: BLIT(FROM, TO, SIZE).
The compiler now recognizes eight significant characters, instead of just
six, in variable and procedure names, etc. The symbol table size has
increased from 254 to 1000 entries. The number of 'QUIT's allowed in a
'LOOP' has increased from 10 to 100. The number of real constants allowed
in scope at one time has increased from 25 to 100.
A "sync" byte may be generated in strings and byte arrays to keep opcodes
and the heap on even-byte boundaries. Beware that consecutive array
RESERVEs will have sync bytes between them if they are not an even number
of bytes long.
The compiled code is position-independent except for multi-dimensional
constant arrays.
INCOMPATABILITIES WITH 6502 XPL
68K XPL terminates strings with a zero byte; 6502 strings are terminated
by setting the MSB on the last character.
6502 XPL stores low byte, high byte in memory; the 68000 stores high
byte, low byte.
68K XPL is limited to 5 levels of static nesting (versus 8 for 6502).
This is only a minor problem since most programs only use 2 or 3 levels.
The compiler uses all 5 levels, but forward procedure declarations could
reduce this.
Consecutive RESERVEs can have sync bytes between them as described above.
If you restart a program on the 68000 a RESERVE will clobber the previous
contents of the first four bytes in the array.
Beware! Even reading an invalid location in a 2-dimentional (or more)
array can cause a 68000 address-error trap to occur.
The 68000 version is missing some intrinsics: TRAP=17, GETERR=22, MOD=58,
PEEK=66 and POKE=67. The floating point intrinsics are currently
accomplished by XPL routines which are declared as linked procedures (and
functions).
The compiled code cannot exceed 32767 bytes. This might be a permanent
restriction since larger programs ought to be broken up into modules
anyway.
With the 32-bit version, there are the following incompatabilities:
Integer array's RESERVE size -- there are now 4 bytes in
an integer (or address) not just 2.
Now there are 8 bytes in a real not just 6.
Watch out for code that assumes 16-bit integers such as
fitting a 128-integer array into one block on the disk.
HEXOUT displays 8 digits instead of 4.
The value $FFFF is now 65535 not -1, etc.
Watch out for code that requires line feeds. Now the last character on a
line is a carriage return. Linefeeds have been banished from all text
files.
The reserved word 'CHAR' has been dropped; use 'ADDR' instead. Also use
'OTHER' in place of 'ELSE' in case statements.
HEAP STATE BEFORE AND AFTER A PROCEDURE CALL
+---+---+---+---+ - - - - - - - - - - -
initial HP --> | 1st | \ \ <-- frame pointer
+---+---+---+---+ | | (Alev)
| 2nd | |-- arguments |
+---+---+---+---+ | |
| 3rd | / |
+---+---+---+---+ |-- local variables
| | |
+---+---+---+---+ |
| | |
+---+---+---+---+ |
| | |
+---+---+---+---+ |
| | /
+---+---+---+---+ - - - - - - - - - - -
| | <-- final HP
+---+---+---+---+
addresses increase
going down |
|
V
+---+ -